package top.rainbowecho.gateway.security.support;

import cn.hutool.core.util.RandomUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.password.PasswordEncoder;
import top.rainbowecho.common.util.UUIDUtil;
import top.rainbowecho.gateway.mapper.UsersMapper;
import top.rainbowecho.gateway.security.authentication.social.qq.api.QqUserInfo;
import top.rainbowecho.model.field.UsersField;
import top.rainbowecho.model.percona.Users;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;

/**
 * 用于处理openId认证
 *
 * @author rainbow
 * @since 2019/12/20 19:06
 */
@Slf4j
public class GatewayOpenIdDetailService implements UserDetailsService {
    private UsersMapper usersMapper;

    private Object userInfo;

    private String remoteIp;

    private PasswordEncoder passwordEncoder;

    @Autowired
    public void setPasswordEncoder(PasswordEncoder passwordEncoder) {
        this.passwordEncoder = passwordEncoder;
    }

    public void setRemoteIp(String remoteIp) {
        this.remoteIp = remoteIp;
    }

    public void setUserInfo(Object userInfo) {
        this.userInfo = userInfo;
    }

    public void setUsersMapper(UsersMapper usersMapper) {
        this.usersMapper = usersMapper;
    }

    @Override
    public UserDetails loadUserByUsername(String openId) throws UsernameNotFoundException {
        log.info("OpenId detail service 准备进行校验");
        QueryWrapper<Users> queryWrapper = new QueryWrapper<Users>().eq(UsersField.OPEN_ID, openId);
        Users users = usersMapper.selectOne(queryWrapper);

        // 如果用户是第一次登录，则对第三方用户信息进行与本地数据库字段的适配，再插入到数据库中
        if (users == null) {
            users = convertToUsers(this.userInfo);
            users.setOpenId(openId);
            users.setIp(this.remoteIp);
            usersMapper.insert(users);
        }

        return new User(users.getUserName(), users.getPassword(), AuthorityUtils.NO_AUTHORITIES);
    }

    private Users convertToUsers(Object userInfo) {
        QqUserInfo qqUserInfo = (QqUserInfo) userInfo;

        String userId = UUIDUtil.randomUuid();
        String password = RandomUtil.randomString(10);
        log.debug("user id 为：" + userId + " 的初始密码为: " + password);
        String encodePassword = this.passwordEncoder.encode(password);
        Users initUser = new Users().setEnable(1).setRegisterTime(LocalDateTime.now())
                .setId(userId)
                .setPassword(encodePassword);

        convert(initUser, qqUserInfo);

        return initUser;
    }

    private void convert(Users initUser, QqUserInfo qqUserInfo) {
        initUser.setProviderId("qq");
        initUser.setProfileUrl(StringUtils.EMPTY);
        initUser.setAvatar(qqUserInfo.getFigureurl_qq_1());
        initUser.setUserName(qqUserInfo.getNickname());
        initUser.setGender(qqUserInfo.getGender_type());
        LocalDate defaultBirthday = LocalDate.of(Integer.parseInt(qqUserInfo.getYear()), 1, 1);
        initUser.setBirthday(defaultBirthday);
        LocalDate now = LocalDate.now();
        long age = ChronoUnit.YEARS.between(defaultBirthday, now);
        initUser.setAge((int) age);
    }
}
